<?php

namespace ltcms\middleware;

class Middleware
{
    private static $_instance;

    private function __construct(){ }
    private function __clone(){ }

    /**
     * 获取类对象
     */
    public static  function getInstance(){
        if(!(self::$_instance instanceof self)){
            self::$_instance=new self();
        }
        return self::$_instance;
    }

    /**
     * 优先级排序
     */
    public function prioritySort($middleware){
        $alias=config("middleware.alias",array());
        $priority=config("middleware.priority",array());

        $useMiddleware=array();
        foreach($middleware as $mval){
            if(isset($alias[$mval])){
                $useMiddleware[$mval]=$alias[$mval];
            }else{
                $useMiddleware[]=$mval;
            }
        }
        $mids=array();
        if($priority && $useMiddleware){
            foreach($priority as $pval){
                if(isset($useMiddleware[$pval])){
                    $mids[]=$useMiddleware[$pval];
                    unset($useMiddleware[$pval]);
                }
            }
            if($useMiddleware){
                foreach($useMiddleware as $aval){
                    array_push($mids,$aval);
                }
            }
        }else{
            $mids=$useMiddleware;
        }
        return $mids;
    }

    /**
     *  派遣中间件
     */
    public function dispatch(\Closure $next,$middleware=array()){
        $request=request();
        $globalMiddleware=config("app.middleware",array());
        $middleware=$this->prioritySort(array_merge($globalMiddleware,$middleware));
        if ($request->pluginsMiddleware){ //如果中间件往请求中添加的中间件,则进行加载
            $middleware=array_merge($middleware,$request->pluginsMiddleware);
        }
        $middlewares=array_reverse($middleware);
        foreach($middlewares as $m){
            if(class_exists($m)){
                $mObj=new $m();
                $next = function($request) use($mObj,$next){
                    return $mObj->handle($request,$next);
                };
            }else{
                throw new \RuntimeException('middleware can\'t exist: ' . $m);
            }
        }
        return $next($request);
    }
}


